﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Microsoft.Surface.Presentation.Controls;
using System.Windows.Media.Animation;

namespace SurfaceCardsGameKit.Tools
{
    public static class DispositionHelper
    {

        public static Duration ComputeAnimationDuration(Point oldPoint, Point newPoint, double oldOrientation, double newOrientation, double ratio)
        {
            if (double.IsNaN(ratio))
                throw new ArgumentException("ratio should not be Nan");
            if (double.IsNaN(oldOrientation))
                throw new ArgumentException("oldOrientation should not be Nan");
            if (double.IsNaN(newOrientation))
                throw new ArgumentException("newOrientation should not be Nan");
            if (double.IsNaN(oldPoint.X) || double.IsNaN(oldPoint.Y))
                throw new ArgumentException("oldPoint should not be Nan");
            if (double.IsNaN(newPoint.X) || double.IsNaN(newPoint.Y))
                throw new ArgumentException("oldPoint should not be Nan");

            var hyp = Math.Sqrt(
                Math.Sqrt(Math.Pow(Math.Abs(newPoint.X - oldPoint.X), 2) + Math.Pow(Math.Abs(newPoint.Y - oldPoint.Y) / 2, 2))
                ) * 2;

            var average = hyp + Math.Abs((newOrientation - oldOrientation) / 10);
            return new Duration(TimeSpan.FromMilliseconds(average * 10 * ratio));
        }

        public static PointAnimation BeginCenterAnimation(ScatterViewItem svi, Point destination, Duration duration)
        {
            StopCenterAnimation(svi);

            PointAnimation pa;

            //if (!double.IsNaN(svi.Center.X) && !double.IsNaN(svi.Center.Y))
                pa = new PointAnimation(svi.ActualCenter, destination, duration, FillBehavior.Stop);
            //else
            //    pa = new PointAnimation(svi.ActualCenter, destination, duration, FillBehavior.Stop);

            pa.Completed += (sender, e) =>
            {
                StopCenterAnimation(svi);
                svi.Center = destination;
            };

            svi.BeginAnimation(ScatterViewItem.CenterProperty, pa);
            return pa;
        }

        public static void StopCenterAnimation(ScatterViewItem svi)
        {
            svi.BeginAnimation(ScatterViewItem.CenterProperty, null);
        }

        public static DoubleAnimation BeginOrientationAnimation(ScatterViewItem svi, double destination, Duration duration)
        {
            StopOrientationAnimation(svi);

            // orientation animation
            DoubleAnimation orientationAnim;

            if (double.IsNaN(svi.ActualOrientation))
                orientationAnim = new DoubleAnimation(destination, duration, FillBehavior.Stop);
            else
                orientationAnim = new DoubleAnimation(svi.ActualOrientation, destination, duration, FillBehavior.Stop);

            orientationAnim.Completed += (sender, ea) =>
            {
                StopOrientationAnimation(svi);
                svi.Orientation = destination;
            };

            svi.BeginAnimation(ScatterViewItem.OrientationProperty, orientationAnim);

            return orientationAnim;
        }

        public static void StopOrientationAnimation(ScatterViewItem svi)
        {
            svi.BeginAnimation(ScatterViewItem.OrientationProperty, null);
        }

        public static double ToRadian(double degrees)
        {
            return degrees * (Math.PI / 180);
        }

        public static double ToDegrees(double radians)
        {
            return radians * (180 / Math.PI);
        }

        public static double CalcOrientationForCards(double from, double to)
        {
            from = CorrectOrientation(from);
            to = CorrectOrientation(to);

            double orientation = to;
            double orientationOffset = 0.0;

            if (from - to > 180)
                orientationOffset = 180;
            else if (from - to < -180)
                orientationOffset = -180;

            if ((from - to - orientationOffset) > 90)
                orientation = 180 + orientationOffset + to;
            else if ((from - to - orientationOffset) < -90)
                orientation = -180 + orientationOffset + to;
            else if (Math.Abs(from - to - orientationOffset) == 90)
                orientation = from;
            else
                orientation = 0 + orientationOffset + to;

            return orientation;
        }

        private static double CorrectOrientation(double orientation)
        {
            if (orientation < 0)
            {
                orientation %= -360;
                orientation = 360 + orientation;
            }
            else
                orientation %= 360;

            return orientation;
        }

    }
}
